<?php


namespace app\home\controller;

use app\base\BaseController;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\Exception;
use think\facade\Db;
use think\facade\View;

/**
 * Class BomForm
 * @package app\home\controller
 * BOM表单
 */
class BomForm extends BaseController
{
    protected $table='bom';
    protected $title='BOM表单';
    private $sessionKey='pageBomForm';
    /**
     * date:2024/3/21
     * 列表
     */
    public function index()
    {
        $param=$this->param;
        if (request()->isAjax()) {

            $where[]=['b.status','>',-1];
                if (isset($param['type'])&&$param['type']){
                    $types=$this->getAllSubIds($param['type']);
                    $types[]=$param['type'];
                    $where[]=['md.type','in',$types];
                }
                if (isset($param['status'])&&$param['status']){
                    $where[]=['b.status','=',$param['status']];
                }
            foreach (['md_code','md_name','md_specs'] as $v){
                if (isset($param[$v])&&$param[$v]){
                    if ($v=='md_code'){
                        $k='md.bar_code';
                    }else{
                        $k=str_replace('_','.',$v);
                    }
                    $where[]=[$k,'like','%'.$param[$v].'%'];
                }
            }

            $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
            $list = Db::name($this->table)->alias('b')
                ->join('material_dossier md','md.id=b.material_dossier_id','left')
                ->where($where)
                ->field('b.*,md.name as mdName,md.specs as mdSpecs,bar_code')
                ->order('b.id DESC')
                ->paginate($rows);
            session($this->sessionKey,$where);
            return table_assign(0, '', $list);
        } else {
            return view();
        }

    }

    /**
     * @return \json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * date:2024/3/21
     * 添加
     */
    public function add()
    {
        $param = get_params();
        if (request()->isAjax()) {
            $postData=$this->param;
            $mxid=$postData['mxid']??[];
            $bom_id=$postData['bom_id']??[];
            $num=$postData['num']??[];
            $material_id=$postData['material_id']??[];
            $loss_rate=$postData['loss_rate']??[];
            $param=[
                'material_dossier_id'=>$postData['material_dossier_id'],
                'is_default'=>$postData['is_default'],
                'status'=>$postData['status'],
                'id'=>$postData['id']??0,
            ];
            if (!$material_id||!$param['material_dossier_id']||!$loss_rate){
                return to_assign(1,'参数缺失');
            }
            if ($postData['is_default']=='是'){
                $wherehave[]=['status','>',-1];
                $wherehave[]=['is_default','=','是'];
                $wherehave[]=['material_dossier_id','=',$postData['material_dossier_id']];
                if (isset($postData['id'])&&$postData['id']){
                    $wherehave[]=['id','<>',$postData['id']];
                }
                $hav=Db::name($this->table)->where($wherehave)->count();
                if ($hav){
                    return to_assign(1,'已有默认bom');
                }
            }

            Db::startTrans();
            $param['update_time']=time();
            $id=$param['id']??0;
            try {
                if ($param['id'] > 0) {
                    Db::name($this->table)->strict(false)->field(true)->update($param);
                    add_log('edit', $param['id'], $param,$this->title);
                } else {
                    $param['create_time'] = time();
                    $id = Db::name($this->table)->strict(false)->field(true)->insertGetId($param);
                    add_log('add', $id, $param,$this->title);
                }
                foreach ($material_id as $k=>$v){
                    if (empty($num[$k])){
                        throw new Exception('参数有误');
                    }
                    $mxData=[
                        'pid'=>$id,
                        'bom_id'=>$bom_id[$k],
                        'material_dossier_id'=>$material_id[$k],
                        'num'=>$num[$k],
                        'loss_rate'=>$loss_rate[$k]??0,
                        'create_time'=>time(),
                        'update_time'=>time()
                    ];
                    if (isset($mxid[$k])&&$mxid[$k]){
                        $mxData['id']=$mxid[$k];
                    }
                    Db::name('bom_detail')->save($mxData);
                }
                Db::commit();
            }catch (\Exception $e){
                Db::rollback();
                return to_assign(1,'操作失败:'.$e->getMessage());
            }

            return to_assign();
        } else {
            $id = isset($param['id']) ? $param['id'] : 0;
            if ($id > 0) {
                $detail = Db::name($this->table)->where('id', $id)->field("*,(select specs from fy_material_dossier md where md.id=material_dossier_id)specs")->find();
                View::assign('detail', $detail);
                $mxList=Db::name('bom_detail')->alias('bd')
                    ->join('material_dossier md','md.id=bd.material_dossier_id')
                    ->where('bd.pid',$id)
                    ->where('bd.status',1)->field("md.bar_code,md.name,md.specs,bd.*")->select();
                View::assign('mxList', $mxList);
            }
            $materialList=Db::name('material_dossier')->where('status','1')->field('id,name,specs')->select();
            $bomList=Db::name($this->table)->where('status',1)->field('id')->select();

            View::assign('id', $id);
            View::assign('bomList', $bomList);
            View::assign('materialList', $materialList);
            return view('form');
        }
    }

    public function addMx()
    {
        if (request()->isPost()) {
//            $where[]=['mdId','>',0];
            $where[]=['status','=',1];
            $where[]=['deleted','=',0];
            foreach (['bar_code','mdName','specs'] as $v){
                if ($v=='mdName'){
                    $v='name';
                }
                if (isset($this->param[$v])&&$this->param[$v]){
                    $where[]=[$v,'like','%'.$this->param[$v].'%'];
                }
            }
            $limit=$this->param['limit']??10;
//            $list=Db::name('material_kucun_view')->where($where)->paginate($limit);
            $list=Db::name('material_dossier')->where($where)->field('*,name as mdName, id as mdId')->paginate(15);

            View::assign('list',$list);
            return table_assign(0, '', $list);
        } else {
            return \view('mx');
        }



}
    public function removeMx()
    {
        $id=$this->param['id'];
        try {
            Db::name('bom_detail')->where('id',$id)->update(['status'=>-1,'update_time'=>time(),'deleted'=>time()]);
            add_log('add', $id, $this->param,$this->title);
        }catch (\Exception $e){
            return to_assign(1,'删除失败:'.$e->getMessage());
        }
        return to_assign();
    }
    /**
     * @return \json
     * @throws \think\db\exception\DbException
     * date:2024/3/21
     * 删除
     */
    public function delete()
    {
        if (request()->isDelete()) {
            $id = get_params("id");
            try {
                Db::name($this->table)->where('id','in',$id)->update(['status'=>-1,'deleted'=>time()]);
                Db::name('bom_detail')->where('pid','in',$id)->update(['status'=>-1,'deleted'=>time()]);
                add_log('delete', $id, request()->param(),$this->title);
            }catch (\Exception $e){
                return to_assign(1, "删除失败".$e->getMessage());
            }
            return to_assign(0, "删除成功");
        } else {
            return to_assign(1, "错误的请求");
        }
    }

    /**
     * @return \json
     * @throws \think\db\exception\DbException
     * date:2024/4/1
     * 启用/禁用
     */
    public function doCheck()
    {
        $param = get_params();
        $param['update_time']=time();
        $res = Db::name($this->table)->strict(false)->field('id,status,update_time')->update($param);
        if ($res) {
            if($param['status'] == 2){
                add_log('disable', $param['id'], $param,$this->title);
            }
            else if($param['status'] == 1){
                add_log('recovery', $param['id'], $param,$this->title);
            }
            return to_assign();
        }
        else{
            return to_assign(0, '操作失败');
        }
    }

    public function importData()
    {
        $errText=[];
        try {
            if (!isset($_FILES['file'])){
                throw new Exception('请选择上传文件');
            }
            //限制上传表格类型
            $fileExtendName = substr(strrchr($_FILES['file']["name"], '.'), 1);
            //application/vnd.ms-excel  为xls文件类型
            if ($fileExtendName != 'xlsx') {
                throw new Exception('必须为excel表格，且必须为xlsx格式！');
            }

            if (is_uploaded_file($_FILES['file']['tmp_name'])) {
                // 有Xls和Xlsx格式两种
//            $objReader = \IOFactory::createReader('Xlsx');
                $objReader = IOFactory::createReader('Xlsx');

                $filename = $_FILES['file']['tmp_name'];

                $objPHPExcel = $objReader->setReadDataOnly(true)->load($filename);  //$filename可以是上传的表格，或者是指定的表格

                $sheet = $objPHPExcel->getSheet(0);   //excel中的第一张sheet
                $highestRow = $sheet->getHighestRow();       // 取得总行数
                $importData = [];
                $fjId=[];
                $sfMr=[];
                $zjbm=[];
                $bom=[];
                $edsl=[];
                $slls=[];

                //循环读取excel表格，整合成数组。如果是不指定key的二维，就用$data[i][j]表示。
                for ($j = 2; $j <= $highestRow; $j++) {
                    $material_code=$objPHPExcel->getActiveSheet()->getCell("A" . $j)->getFormattedValue();
                    $material_dossier_id=Db::name('material_dossier')->where('bar_code',$material_code)->where('status','1')->value('id');
                 if ($material_dossier_id){
                    $is_default=$objPHPExcel->getActiveSheet()->getCell("B" . $j)->getFormattedValue();
                    if (!$material_dossier_id){
                        $warText="第".($j-1) ."行父件填写有误1";
                        throw new Exception($warText);
                    }
                    $sonCode =$objPHPExcel->getActiveSheet()->getCell("C" . $j)->getFormattedValue();
                    $sonId=Db::name('material_dossier')->where('bar_code',$sonCode)->where('status','1')->value('id');
//                    $sonId=Db::name('material_kucun_view')->where('bar_code',$sonCode)->value('mdId');
                    if (!$sonId){
                        $warText="第".($j-1) ."行填写子件编码有误2";
//                        throw new Exception($warText);
                        $errText[]=$sonCode.'未入库';
                    }
                    $bomId=$objPHPExcel->getActiveSheet()->getCell("D" . $j)->getFormattedValue();
                    $edNum=(float)$objPHPExcel->getActiveSheet()->getCell("E" . $j)->getFormattedValue();
                    if (!$edNum){
                        $warText="第".($j-1) ."行额定数量填写有误3";
                        throw new Exception($warText);
                    }
                    $shl=$objPHPExcel->getActiveSheet()->getCell("F" . $j)->getFormattedValue();
                    $fjId[]=$material_dossier_id;
                    $sfMr[]=$is_default;
                    $zjbm[]=$sonId;
                    $bom[]=$bomId;
                    $edsl[]=$edNum;
                    $slls[]=$shl;

                    $importData[] = [
                       'fjId'=>$material_dossier_id,
                        'sfmr'=>$is_default,
                        'zjbm'=>$sonCode,
                        'bomId'=>$bomId,
                        'edsl'=>$edNum,
                        'shl'=>$shl
                    ] ;
                }
                }
                if ($errText){
                    throw new Exception('导入失败');
                }
                $res=$this->doImporData($fjId,$sfMr,$zjbm,$bom,$edsl,$slls);
                if ($res['code']!=200){
                    throw new Exception($res['msg']);
                }
                $data=$res['data'];
                $zbData=$data['pData'];
                $id=Db::name($this->table)->insertGetId($zbData);
                $sonData=$data['sonData'];
                foreach ($sonData as &$v){
                    $v['pid']=$id;
                }
               Db::name("bom_detail")->insertAll($sonData);
                if ($importData){
//                    Db::name($this->table)->insertAll($importData);
                    add_log('import', '', $importData,$this->title);
                }

            }
        }catch (Exception $e){
            add_log('import', '', $e->getMessage(),$this->title);
            return to_assign(1,'操作失败:'.$e->getMessage(),$errText);
        }
        return to_assign();

    }

    public function doImporData($fjid,$sfmr,$zjbm,$bomId,$edsh,$shl)
    {
        $fjid1=array_unique($fjid);
        $sfmr1=array_unique($sfmr);
//        if (count($fjid1)<1){
//            return ['code'=>400,'msg'=>'父件物料不存在'];
//        }
        if (count($fjid1)!=1){
            return ['code'=>400,'msg'=>'父件物料填写有误'];
        }

        if (count($sfmr1)!=1){
            if (count($fjid1)!=1){
                return ['code'=>400,'msg'=>'是否默认填写有误'];
            }
        }
        if ($sfmr1[0]=='是'){
            $wherehave[]=['status','>',-1];
            $wherehave[]=['is_default','=','是'];
            $wherehave[]=['material_dossier_id','=',$fjid1[0]];
            $hav=Db::name($this->table)->where($wherehave)->count();
            if ($hav){
                return  ['code'=>400,'msg'=>'已有默认bom'];
            }
        }
        $zbData=[
            'material_dossier_id'=>$fjid1[0],
            'is_default'=>$sfmr1[0],
            "deleted" =>0,
            "create_time"=>time(),
            'update_time'=>time()

        ];
        $data=[];
        foreach ($zjbm as $k=>$v){
            $data[]=[
                'material_dossier_id'=>$zjbm[$k],
                'num'=>$edsh[$k],
                'loss_rate'=>isset($shl[$k])&&$shl[$k]?$shl[$k]:0,
                'bom_id'=>isset($bomId[$k])&&$bomId[$k]?$bomId[$k]:0,
                "deleted" =>0,
                "create_time"=>time(),
                'update_time'=>time()
            ];
        }
        return ['code'=>200,'msg'=>'ok','data'=>['pData'=>$zbData,'sonData'=>$data]];
    }

    public function exportData()
    {
        $where=session($this->sessionKey);
        $list = Db::name($this->table)->alias('b')
            ->join('material_dossier md','md.id=b.material_dossier_id','left')
            ->where($where)
            ->field('b.*,md.name as mdName,md.specs as mdSpecs,bar_code')
            ->order('b.id DESC')->select()->each(function ($item){
                $item['status']=$item['status']==1?'启用':'禁用';
                return $item;
            });
        $title = [
            'id' => 'ID',
            'mdName' => '父件',
            'bar_code' => '物料编码',
            'mdSpecs' => '规格型号',
            'is_default' => '是否默认',
            'status' => '状态',
        ];
        $name =$this->title;
        exportXlsData($name,$title,$list);
        exit();
    }
}